﻿#include "dealchartdata.h"

#include <QProgressDialog>
#include <QApplication>
#include <QSettings>
#include <QDate>

DealChartData::DealChartData(QObject* parent) : QObject(parent)
{
	m_nIndex = 0;

	m_nCount = 50;

	m_nUnit = 0;

	m_nRow = 0;

	m_nPos = 0;

	m_bPos = false;

	m_bDiscontinue = false;

	m_nView = 0;
}

QMap<QString, QMap<QString, long long> > DealChartData::getBarData()
{
	QMap<QString, long long> map;
	QMap<QString, long long>::const_iterator i;
	barData.clear();
	for (i = qBarDatas.constBegin(); i != qBarDatas.constEnd(); ++i) {
		map.insert(TM, i.value());
		barData.insert(i.key(), map);
	}
	return barData;
}

QMap<QString, QMap<QString, long long>> DealChartData::getLineData()
{
	QMap<QString, long long> map;
	quint32 nValue = 0;
	QMap<QString, long long>::const_iterator i;

	lineData.clear();
	for (int i = 0; i < qLineDatas.size(); i++)
	{
		nValue = qLineDatas[i];
		if (i + 1 == qLineDatas.size())
		{
			break;
		}
		map.insert(TM, (qLineDatas[i + 1] - nValue) / 10);
		lineData.insert(QString::number(i), map);
	}

	return lineData;
}

QMap<double, double> DealChartData::getSplineData()
{
	QMap<double, double> prob_data;
	double dAvg = m_db.getAvgValue();
	double dVar = m_db.getVariance();
	double nCount = m_db.getAllCount();

	m_strInfo = tr("count:%1     avg:%2   variance:%3   max:%4   min:%5").arg(nCount).arg(dAvg).arg(dVar).arg(m_db.getMaxValue()).arg(m_db.getMinValue());
	double nRigth = 0;
	double nLeft = 0;
	prob_data.insert(0, 0);
	for (int i = 0; i < 5; i++)
	{
		nRigth = m_db.selectRangeCount(dAvg + dVar * i, dAvg + dVar * (i + 1));
		nLeft = m_db.selectRangeCount(dAvg - dVar * (i + 1), dAvg - dVar * i);
		if (i == 0)
		{
			prob_data.insert(dAvg, (nRigth + nLeft) / nCount);
		}

		if (dAvg - dVar * (i + 1) > 0)
		{
			prob_data.insert(dAvg - dVar * (i + 1), (nLeft) / nCount);
		}
		prob_data.insert(dAvg + dVar * (i + 1), (nRigth) / nCount);
	}
	return prob_data;
}

QMap<int, int> DealChartData::getNormalityDtata()
{
	return m_db.selectRepetRecords();
}

int DealChartData::getSplieMaxData()
{
	return m_db.getMaxValue();
}

void DealChartData::splitBarData()
{
	loadBarRecord();
}

void DealChartData::splitLineData()
{
	loadLineRecord();
}

bool DealChartData::isCreateTab(const QString& fileName)
{
	return m_db.isExistTab(fileName);
}

void DealChartData::initData(const QString& fileName, int nIndex)
{
	if (fileName.isEmpty())
	{
		return;
	}
	file.setFileName(fileName);
	m_nIndex = nIndex;

	QSettings settings;
	int data_size = settings.value("chartSetting/data_size", 0).toInt();
	if (data_size == 0) {
		data_size = 20;
		settings.setValue("chartSetting/data_size", data_size);
	}
	int x_unit = settings.value("chartSetting/x_axis_interval/unit", 0).toInt();
	m_nCount = data_size;
	m_nUnit = x_unit;
	clear();
	calcRecords();
}

void DealChartData::initDB()
{
	m_db.init();
}

void DealChartData::disDB()
{
	m_db.disConnection();
}

void DealChartData::initSplinData(const QString& fileName)
{
	if (fileName.isEmpty())
	{
		return;
	}
	file.setFileName(fileName);
	if (m_db.createTabel(fileName))
	{
		clear();
		calcSplineRecords();
	}
}

void DealChartData::clear()
{
	records.clear();
	qLineDatas.clear();
	barData.clear();
	lineData.clear();
	qBarDatas.clear();

	m_nRow = 0;
	m_nPos = 0;
	m_bPos = false;
}

bool DealChartData::calcRecords()
{
	int nPos = 0;
	int nSkip = 0;
	if (m_nView == 1) {
		nPos = 22;
		nSkip = 22;
	}
	else {
		nPos = 32;
		nSkip = 30;
	}
	m_bPos = false;
	quint16 len = 0;
	qint64 size = file.size();
	qint64 pos = records.isEmpty() ? 0 : records.last();
	if (file.open(QIODevice::ReadOnly)) {
		QProgressDialog progress(tr("Calculate all records: "), tr("Cancel"), pos, size, qApp->activeWindow());
		progress.setWindowTitle(tr("Progress"));
		progress.setModal(true);
		file.seek(pos);
		QDataStream is(&file);
		is.setByteOrder(QDataStream::LittleEndian);
		while (size - file.pos() >= nPos) {
			is.skipRawData(nSkip);
			is >> len;
			is.skipRawData(len);
			records.push_back(file.pos());
			if (records.size() == COUNT * (m_nPos + 1))
			{
				m_nPos++;
				m_bPos = true;
				file.close();
				return true;
			}
			progress.setValue(file.pos());
			qApp->processEvents();
			if (progress.wasCanceled()) {
				file.close();
				return false;
			}
		}
		file.close();
	}
	return true;
}


bool DealChartData::calcSplineRecords()
{
	quint16 len = 0;
	qint64 size = file.size();
	qint64 pos = records.isEmpty() ? 0 : records.last();
	records.clear();
	qRow = qreal(pos) / qreal(size);
	int x = 0;
	if (m_bDiscontinue)
	{
		clear();
		return true;
	}
	if (file.open(QIODevice::ReadOnly)) {
		file.seek(pos);
		QDataStream is(&file);
		is.setByteOrder(QDataStream::LittleEndian);
		while (size - file.pos() >= 32) {
			if (m_bDiscontinue)
			{
				clear();
				file.close();
				return true;
			}
			x++;
			is.skipRawData(30);
			is >> len;
			is.skipRawData(len);
			records.push_back(file.pos());

			if (records.size() == SPILECOUNT)
			{
				m_nPos++;
				file.close();
				m_db.insertData(records);
				calcSplineRecords();
				return true;
			}
		}
		file.close();
		m_db.insertData(records);
	}
	return true;
}

int DealChartData::maxDisplaySize() const
{
	QSettings settings;
	int size = settings.value("PDXP/maxDisplaySize", 0).toInt();
	if (0 == size) {
		size = 1024;
		settings.setValue("PDXP/maxDisplaySize", size);
	}
	return size;
}

void DealChartData::loadBarRecord()
{
	QProgressDialog progress(tr("Calculate all records: "), tr("Cancel"), 0, records.size(), qApp->activeWindow());
	progress.setWindowTitle(tr("Progress"));
	progress.setModal(true);
	qBarDatas.clear();
	for (int row = m_nRow; row < records.size(); row++) {
		qint64 pos = row > 0 ? records.at(row - 1) : 0;
		if (file.open(QIODevice::ReadOnly)) {
			file.seek(pos);
			int size = records.at(row) - pos;
			int displaySize = maxDisplaySize();
			if (size > displaySize)
				size = displaySize;
			record = file.read(size);
			file.close();
			QDataStream in(record);
			if (m_nView == 1) {
				in >> udf;
				progress.setValue(row);
				qApp->processEvents();
				if (progress.wasCanceled()) {
					return;
				}
				if (m_nUnit)
				{
					qBarDatas[jsBarMinString(udf.JS)]++;
				}
				else {
					qBarDatas[jsBarSecString(udf.JS)]++;
				}
				if (qBarDatas.size() > m_nCount)
				{
					if (m_nUnit)
					{
						qBarDatas.remove(jsBarMinString(udf.JS));
					}
					else {
						qBarDatas.remove(jsBarSecString(udf.JS));
					}
					m_nRow = row;
					return;
				}

			}
			else {
				in >> pdxp;
				progress.setValue(row);
				qApp->processEvents();
				if (progress.wasCanceled()) {
					return;
				}
				if (m_nUnit)
				{
					qBarDatas[jsBarMinString(pdxp.JS)]++;
				}
				else {
					qBarDatas[jsBarSecString(pdxp.JS)]++;
				}
				if (qBarDatas.size() > m_nCount)
				{
					if (m_nUnit)
					{
						qBarDatas.remove(jsBarMinString(pdxp.JS));
					}
					else {
						qBarDatas.remove(jsBarSecString(pdxp.JS));
					}
					m_nRow = row;
					return;
				}
			}
		}
	}
}


void DealChartData::loadLineRecord()
{
	QProgressDialog progress(tr("Calculate all records: "), tr("Cancel"), 0, records.size(), qApp->activeWindow());
	progress.setWindowTitle(tr("Progress"));
	progress.setModal(true);
	qLineDatas.clear();
	for (int row = m_nRow; row < records.size(); row++) {
		qint64 pos = row > 0 ? records.at(row - 1) : 0;
		if (file.open(QIODevice::ReadOnly)) {
			file.seek(pos);
			int size = records.at(row) - pos;
			int displaySize = maxDisplaySize();
			if (size > displaySize)
				size = displaySize;
			record = file.read(size);
			file.close();
			QDataStream in(record);
			if (m_nView == 1) {
				in >> udf;
				qLineDatas.append(udf.JS);
			}
			else {
				in >> pdxp;
				qLineDatas.append(pdxp.JS);
			}
			if (qLineDatas.size() > m_nCount)
			{
				m_nRow = row;
				return;
			}
		}
		progress.setValue(row);
		qApp->processEvents();
		if (progress.wasCanceled()) {
			return;
		}
	}
}

void DealChartData::fetchMore()
{
	calcRecords();
}

void DealChartData::getProssBarValue(int& row1, int& row2, int& rowMax2)
{
	row1 = int(qRow * 100);
	m_db.getProssBarValue(row2, rowMax2);
}

void DealChartData::DiscontinueInsert()
{
	m_db.m_bDiscontinue = true;
}


QString DealChartData::jsBarSecString(quint32 js)
{
	QTime time(0, 0);
	return QString("%1").arg(time.addMSecs(js / 10).toString("HH:mm:ss"));
}

QString DealChartData::jsBarMinString(quint32 js)
{
	QTime time(0, 0);
	return QString("%1").arg(time.addMSecs(js / 10).toString("HH:mm"));
}

QString DealChartData::jsLineString(quint32 js)
{
	QTime time(0, 0);
	return QString("%1%2").arg(time.addMSecs(js / 10).toString("HH:mm:ss.zzz")).arg(js % 10);
}
